#include "componentpinmanager.h"

#include <QtCore/qdebug.h>
#include <QtGui/qboxlayout.h>
#include <QtGui/qcombobox.h>
#include <QtGui/qgroupbox.h>
#include <QtGui/qicon.h>
#include <QtGui/qlabel.h>
#include <QtGui/qmenu.h>
#include <QtGui/qplaintextedit.h>
#include <QtGui/qpushbutton.h>

#include <QtGui/qtoolbutton.h>

PinSyntaxHighlighter::PinSyntaxHighlighter(QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    m_elements["Group"].format.setForeground(Qt::darkMagenta);
    m_elements["Comment"].format.setForeground(Qt::darkGreen);
    m_elements["Separator"].format.setBackground(Qt::lightGray);
    m_elements["Name"].format.setFontWeight(QFont::Bold);
    m_elements["Number"].format.setForeground(Qt::blue);
    m_elements["Options"].format.setForeground(Qt::gray);
}

void PinSyntaxHighlighter::highlightBlock(const QString &text)
{
    if (parse(text))
    {
        foreach (QString elem, m_elements.keys())
            if (m_elements[elem].index >= 0)
                setFormat(m_elements[elem].index,
                          m_elements[elem].text.length(),
                          m_elements[elem].format);
    }
    else
    {
        QTextCharFormat errorFormat;
        errorFormat.setForeground(Qt::red);
        setFormat(0, text.length(), errorFormat);
    }
}

bool PinSyntaxHighlighter::parse(const QString &text)
{
    int idx;
    int groupOffset = 0;
    int nameOffset = 0;
    int numberOffset = 0;

    QRegExp groupExp("^([^:\\s]+)(:)");
    idx = m_elements["Group"].index = groupExp.indexIn(text);
    if (idx >= 0)
    {
        m_elements["Group"].text = groupExp.cap(1);
        groupOffset = idx + groupExp.matchedLength();
    }

    QRegExp commentExp("//[^\n]*");
    idx = m_elements["Comment"].index = commentExp.indexIn(text);
    if (idx >= 0)
        m_elements["Comment"].text = commentExp.cap(0);

    QRegExp separatorExp("^\\s*[-]{2,}");
    idx = m_elements["Separator"].index = separatorExp.indexIn(text, groupOffset, QRegExp::CaretAtOffset);
    if (idx >= 0)
        m_elements["Separator"].text = separatorExp.cap(0);

    QRegExp nameExp("^\\s*(?!\\s*[-]{2,})(?!\\s*//)[^\\[]+");
    idx = m_elements["Name"].index = nameExp.indexIn(text, groupOffset, QRegExp::CaretAtOffset);
    if (idx >= 0)
    {
        m_elements["Name"].text = nameExp.cap(0);
        nameOffset = idx + nameExp.matchedLength();
    }

    QRegExp numberExp("^\\s*\\[[-,\\d\\w\\s]+\\]");
    idx = m_elements["Number"].index = numberExp.indexIn(text, nameOffset, QRegExp::CaretAtOffset);
    if (idx >= 0)
    {
        m_elements["Number"].text = numberExp.cap(0);
        numberOffset = idx + numberExp.matchedLength();
    }

    QRegExp optionsExp("^\\s*(((([IOZ]/?)+)|(P(U|D))|[-+ox])\\s*)*");
    idx = m_elements["Options"].index = optionsExp.indexIn(text, numberOffset, QRegExp::CaretAtOffset);
    if (idx >= 0)
        m_elements["Options"].text = optionsExp.cap(0);

    return true;
}

ComponentPinManager::ComponentPinManager(QWidget *parent) :
    QWidget(parent)
{
    QMenu *addMenu = new QMenu;
    QAction *act;
    act = new QAction(tr("Pin"), this);
    addMenu->addAction(act);
    act = new QAction(tr("Separator"), this);
    addMenu->addAction(act);

    QPushButton *addButton = new QPushButton(tr("Add"));
    addButton->setMenu(addMenu);

    QPushButton *convertButton = new QPushButton(tr("Convert..."));
    QPushButton *clearButton = new QPushButton(tr("Clear all"));

    QHBoxLayout *buttonsLayout = new QHBoxLayout;
    buttonsLayout->addWidget(addButton);
    buttonsLayout->addWidget(convertButton);
    buttonsLayout->addWidget(clearButton);

    m_group = new QComboBox;
    m_group->addItem(tr("All"));
    m_group->addItem(tr("Default"));

    QToolButton *addGroupButton = new QToolButton;
    addGroupButton->setIcon(QIcon(":/images/add.png"));

    QToolButton *editGroupButton = new QToolButton;
    editGroupButton->setIcon(QIcon(":/images/edit.png"));

    QToolButton *deleteGroupButton = new QToolButton;
    deleteGroupButton->setIcon(QIcon(":/images/delete.png"));

    QHBoxLayout *groupLayout = new QHBoxLayout;
    groupLayout->addWidget(new QLabel(tr("Group:")));
    groupLayout->addWidget(m_group, 1);
    groupLayout->addWidget(addGroupButton);
    groupLayout->addWidget(editGroupButton);
    groupLayout->addWidget(deleteGroupButton);

    m_pinList = new QPlainTextEdit;
    m_pinList->setLineWrapMode(QPlainTextEdit::NoWrap);
    /*QFont myFont;
    myFont.setFamily("Courier");
    myFont.setFixedPitch(true);
    myFont.setPointSize(8);
    m_pinList->setFont(myFont);*/

    m_highlignter = new PinSyntaxHighlighter(m_pinList->document());
    m_pinList->setPlainText(tr("// Example") + "\n"
                           "~CE [1] o\n"
                           "R/~W [2]\n"
                           "NC [3,4] x\n"
                           "-- // Separator\n"
                           "A [5-8] O PU\n"
                           "D [9-14] IOZ\n"
                           "Power:Vcc [15] +\n"
                           "Power:GND [16] -\n" +
                           tr("// You can edit this list directly ...") + "\n" +
                           tr("// ... or convert from other format.") + "\n" +
                           tr("// Press \"Clear all\" button to start with your own pin list."));

    QVBoxLayout *pinsLayout = new QVBoxLayout;
    pinsLayout->addLayout(buttonsLayout);
    pinsLayout->addLayout(groupLayout);
    pinsLayout->addWidget(m_pinList, 1);

    QGroupBox *pinsGroup = new QGroupBox(tr("Pin list"));
    pinsGroup->setLayout(pinsLayout);

    QGroupBox *propertiesGroup = new QGroupBox(tr("Pin properties"));
    //pinsGroup->setLayout(pinsLayout);

    QVBoxLayout *mainLayout = new QVBoxLayout;

    mainLayout->addWidget(pinsGroup, 1);
    mainLayout->addWidget(propertiesGroup);

    setLayout(mainLayout);
}

